var scene, light, camera, mesh, geometry, renderer;
var canvas, container, stats, monitor;
var width = window.innerWidth,
  height = window.height;
var cameraParams = {},
  lightParams = {};

function initEnv() {
  container = document.getElementById("container");
  width = window.innerWidth;
  height = window.innerHeight;

  var light1 = new THREE.DirectionalLight(0xffffff, 0.5);
  light1.position.set(1, 1, 1);

  var light2 = new THREE.DirectionalLight(0xffffff, 1.5);
  light2.position.set(0, -1, 0);

  camera = new THREE.PerspectiveCamera(45, width / height, 1, 3500);
  
  light = new THREE.AmbientLight(0x444444);
  scene = new THREE.Scene();
  scene.fog = new THREE.Fog(0x050505, 2000, 3500);
  geometry = new THREE.BufferGeometry();

  material = new THREE.MeshPhongMaterial({
    color: 0xaaaaaa, specular: 0xffffff, shininess: 250,
    side: THREE.FrontSide, vertexColors: THREE.VertexColors
  });
  mesh = new THREE.Mesh(geometry, material);
  renderer = new THREE.WebGLRenderer({ antialias: false });
  canvas = renderer.domElement;

  camera.position.z = 2750;
  scene.add(light);
  scene.add(light1);
  scene.add(light2);
  scene.fog = new THREE.Fog(0x050505, 2000, 3500);
  renderer.setClearColor(0x444444);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  container.appendChild(canvas);
}

function initStatus() {
  scene.add(new THREE.AmbientLight(0x444444));
 
  stats = new Stats();
  stats.domElement.style.position = "absolute";
  stats.domElement.style.top = "0px";
  container.appendChild(stats.domElement);
  container.appendChild(renderer.domElement);
}

function initMonitor() {
  // lightParams.x = 0;
  // lightParams.y = 0;
  // lightParams.z = 0;
  // lightParams.decay = 1;

  cameraParams.up = {};
  cameraParams.x = 0;
  cameraParams.y = 0;
  cameraParams.z = 2750;
  // cameraParams.up.x = 0;
  // cameraParams.up.y = 1;
  // cameraParams.up.z = 0;

  monitor = new DAT.GUI();
  monitor.add(cameraParams, "x", -2000, 2000).name("相机X的位置");
  monitor.add(cameraParams, "y", -2000, 2000).name("相机Y的位置");
  monitor.add(cameraParams, "z", -2000, 5000).name("相机Z的位置");
  // monitor.add(cameraParams.up, "x", -1, 1).name("相机up.x的位置");
  // monitor.add(cameraParams.up, "y", -1, 1).name("相机up.y的位置");
  // monitor.add(cameraParams.up, "z", -1, 1).name("相机up.z的位置");

  // monitor.add(lightParams, "x", -2000, 2000).name("点光源X的位置");
  // monitor.add(lightParams, "y", -2000, 2000).name("点光源Y的位置");
  // monitor.add(lightParams, "z", -2000, 2000).name("点光源Z的位置");
  // monitor.add(lightParams, "decay", 0, 1).name("衰减");
}

function onWindowResize() {
  width = window.innerWidth;
  height = window.innerHeight;
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function genTri() {
  var trigangles = 1600000 / 2;
  var positions = new Float32Array(trigangles * 3 * 3);
  var normals = new Float32Array(trigangles * 3 * 3);
  var colors = new Float32Array(trigangles * 3 * 3);
  var color = new THREE.Color();

  var n = 800, n2 = n / 2;
  var d = 12, d2 = d / 2;

  var pa = new THREE.Vector3();
  var pb = new THREE.Vector3();
  var pc = new THREE.Vector3();

  var cb = new THREE.Vector3();
  var ab = new THREE.Vector3();

  for (var i = 0; i < positions.length; i += 9) {
    var x = Math.random() * n - n2;
    var y = Math.random() * n - n2;
    var z = Math.random() * n - n2;

    var ax = x + Math.random() * d - d2;
    var ay = y + Math.random() * d - d2;
    var az = z + Math.random() * d - d2;

    var bx = x + Math.random() * d - d2;
    var by = y + Math.random() * d - d2;
    var bz = z + Math.random() * d - d2;

    var cx = x + Math.random() * d - d2;
    var cy = y + Math.random() * d - d2;
    var cz = z + Math.random() * d - d2;

    positions[i] = ax;
    positions[i + 1] = ay;
    positions[i + 2] = az;

    positions[i + 3] = bx;
    positions[i + 4] = by;
    positions[i + 5] = bz;

    positions[i + 6] = cx;
    positions[i + 7] = cy;
    positions[i + 8] = cz;

    pa.set(ax, ay, az);
    pb.set(bx, by, bz);
    pc.set(cx, cy, cz);

    cb.subVectors(pc, pb);
    ab.subVectors(pa, pb);
    cb.cross(ab);

    cb.normalize();

    var nx = cb.x;
    var ny = cb.y;
    var nz = cb.z;

    normals[i] = nx;
    normals[i + 1] = ny;
    normals[i + 2] = nz;

    normals[i + 3] = nx;
    normals[i + 4] = ny;
    normals[i + 5] = nz;

    normals[i + 6] = nx;
    normals[i + 7] = ny;
    normals[i + 8] = nz;

    // colors

    var vx = (x / n) + 0.5;
    var vy = (y / n) + 0.5;
    var vz = (z / n) + 0.5;

    color.setRGB(vx, vy, vz);

    colors[i] = color.r;
    colors[i + 1] = color.g;
    colors[i + 2] = color.b;

    colors[i + 3] = color.r;
    colors[i + 4] = color.g;
    colors[i + 5] = color.b;

    colors[i + 6] = color.r;
    colors[i + 7] = color.g;
    colors[i + 8] = color.b;
  }
  geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
  geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));
  geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));

  geometry.computeBoundingSphere();
  scene.add(mesh);
  renderer.setClearColor(scene.fog.color);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.gammaInput = true;
  renderer.gammaOutput = true;
  container.appendChild(renderer.domElement);
}

function updateEnv() {
  camera.position.x = cameraParams.x;
  camera.position.y = cameraParams.y;
  camera.position.z = cameraParams.z;
  camera.updateProjectionMatrix();
}

function animate() {
  updateEnv();
  render();
  stats.update();
  requestAnimationFrame(animate);
}

function render() {

  var time = Date.now() * 0.001;

  mesh.rotation.x = time * 0.25;
  mesh.rotation.y = time * 0.5;

  renderer.render(scene, camera);

}

function threeStart() {
  initEnv();
  initStatus();
  initMonitor();
  genTri();
  animate();
}
